package com.sinaapp.zhangziyou.service;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sinaapp.zhangziyou.dao.EmailValDao;
import com.sinaapp.zhangziyou.dao.MenuDao;
import com.sinaapp.zhangziyou.dao.RoleDao;
import com.sinaapp.zhangziyou.dao.RoleMenuDao;
import com.sinaapp.zhangziyou.dao.UserDao;
import com.sinaapp.zhangziyou.dao.UserRoleDao;
import com.sinaapp.zhangziyou.model.PageData;
import com.sinaapp.zhangziyou.model.UserInfo;
import com.sinaapp.zhangziyou.pojo.EmailValEntity;
import com.sinaapp.zhangziyou.pojo.MenuEntity;
import com.sinaapp.zhangziyou.pojo.RoleEntity;
import com.sinaapp.zhangziyou.pojo.RoleMenu;
import com.sinaapp.zhangziyou.pojo.UserEntity;
import com.sinaapp.zhangziyou.pojo.UserRole;
import com.sinaapp.zhangziyou.utils.CodeGenerator;
import com.sinaapp.zhangziyou.utils.DEncryptionUtils;
import com.sinaapp.zhangziyou.utils.DateUtil;
import com.sinaapp.zhangziyou.utils.EmailUtil;
import com.sinaapp.zhangziyou.utils.MD5;
import com.sinaapp.zhangziyou.utils.UUIDGenerator;
import com.sinaapp.zhangziyou.utils.ValidatorUtil;

@Service
public class UCenterService {

	private static Logger logger = LoggerFactory.getLogger(UCenterService.class);
	
	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private RoleMenuDao roleMenuDao;
	@Autowired
	private UserRoleDao userRoleDao;
	@Autowired
	private EmailValDao emailValDao;
	
	public UserEntity getUserByUserName(String userName){
		
		try {
			UserEntity ue=this.userDao.getUserByName(userName);
		HashSet<RoleEntity> set=	(HashSet<RoleEntity>) ue.getRoles();
		for(RoleEntity s:set){
		System.out.println(s.getRoleName());	
		}
			return this.userDao.getUserByName(userName);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("查用户 "+userName+" 数据出错");
		}
		return null;
		
	}
	
	public UserEntity getUser(String id){
		return this.userDao.getUserById(id);
	}
	
	@Transactional
	public void updateUserStatus(String id,int status){
		Map prmMap=new HashMap<String,Object>(2);
		prmMap.put("id", id);
		prmMap.put("status", status);
		this.userDao.updateUserStatus(prmMap);
	}
	
	@Transactional(readOnly = false)
	public void delUser(String userId){
		// 用户角色表也删
		userRoleDao.deleteByUserId(userId);
		 this.userDao.delUser(userId);
	}
	
	public void delUsers(String[] userIds){
		// 用户角色表也删
		
		userRoleDao.deleteByUserIds(userIds);
		
		 this.userDao.delUsers(userIds);
	}
	
	public boolean saveUser(UserEntity userEntity) {
		String userId = userEntity.getId();
		String userName = userEntity.getUserName();
		String passWord = userEntity.getPassWord();
		
		if (!userId.isEmpty()) {
			UserEntity updateEntity = this.userDao.getUserById(userId);
			
			updateEntity.setStatus(userEntity.getStatus());
			updateEntity.setUserName(userName);
			updateEntity.setLastUpdate(DateUtil.getCurrentTime());
			
			if(StringUtils.isNotBlank(passWord)){
				updateEntity.setPassWord(DEncryptionUtils.standPwdEncoder(passWord));
			}
			
			try {
				this.userDao.update(updateEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
		}else{
			//新增
			if(this.userDao.existUser(userName)>0){
				return false;
			}
			
			if(StringUtils.isBlank(passWord)){
				//新增用户，如果用户没有输入密码，则设置默认的密码
				passWord = "123456";
			}
			userEntity.setId(UUIDGenerator.getUUID());
			userEntity.setCreateTime(DateUtil.getCurrentTime());
			userEntity.setLastUpdate(DateUtil.getCurrentTime());
			userEntity.setPassWord(DEncryptionUtils.standPwdEncoder(passWord));
			
			try {
				this.userDao.save(userEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
			
		}
		
		return true;
	}
	
	public RoleEntity getRole(String id){
		return this.roleDao.getRoleById(id);
	}
	
	
	@Transactional
	public int updateRoleStatus(String id,int status){
		return this.roleDao.updateRoleStatus(id, status);
	}
	
	@Transactional
	public int delRole(String roleId){
		// 删除用户对应的角色 用户角色表也要删，角色菜单表也删
		roleMenuDao.deleteByRoleId(roleId);
		return this.roleDao.delRole(roleId);
	}
	
	public boolean saveRole(RoleEntity roleEntity) {
		String roleId = roleEntity.getId();
		String roleName = roleEntity.getRoleName();
		if (!roleId.isEmpty()) {
			RoleEntity updateEntity = this.roleDao.getRoleById(roleId);
			
			updateEntity.setStatus(roleEntity.getStatus());
			updateEntity.setRoleName(roleName);
			updateEntity.setLastUpdate(DateUtil.getCurrentTime());

			
			try {
				this.roleDao.update(updateEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				
				return false;
			}
		}else{
			//新增	
			roleEntity.setId(UUIDGenerator.getUUID());
			roleEntity.setCreateTime(DateUtil.getCurrentTime());
			roleEntity.setLastUpdate(DateUtil.getCurrentTime());
			
			try {
				this.roleDao.save(roleEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
			
		}
		
		return true;
	}
	
	public MenuEntity getMenu(String menuId){
		return this.menuDao.getMenuById(menuId);
	}

	@Transactional
	public int delMenu(String id){
		// 角色菜单表也要删除
		roleMenuDao.deleteByMenuId(id);
		return this.menuDao.delMenu(id);
	}
	//得到可用的 状态为1的角色
	public List<RoleEntity> getAvailableRoles(){
		return this.roleDao.getRoles(1);
	}
	
	public List<MenuEntity> getAllNavMenus(){
		return this.menuDao.getAllNavMenus(1);
		
	}
	
	public List<MenuEntity> getAllMenus(){
		return this.menuDao.getAllMenus();
		
	}
	
	public List<MenuEntity> getChildMenus(String parentId) {
		return this.menuDao.getChildMenus(parentId);
	}
	
	
	
	public boolean saveMenu(MenuEntity menuEntity) {
		String menuId = menuEntity.getId();
		String menuName = menuEntity.getMenuName();
		if (!menuId.isEmpty()) {
			MenuEntity updateEntity = this.menuDao.getMenuById(menuId);
			
			updateEntity.setMenuName(menuName);
			updateEntity.setParentId(menuEntity.getParentId());
			updateEntity.setMenuCode(menuEntity.getMenuCode());
			updateEntity.setMenuUrl(menuEntity.getMenuUrl());
			updateEntity.setNavMenu(menuEntity.getNavMenu());
			updateEntity.setLastUpdate(DateUtil.getCurrentTime());

			
			try {
				this.menuDao.update(updateEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
		}else{
			//新增		
			menuEntity.setId(UUIDGenerator.getUUID());
			menuEntity.setCreateTime(DateUtil.getCurrentTime());
			menuEntity.setLastUpdate(DateUtil.getCurrentTime());
			
			try {
				this.menuDao.save(menuEntity);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
			
		}
		
		
		return true;
	}
	
	public PageData<UserEntity> getUsers(int pageIndex, int pageSize,String userName){
		
		PageData<UserEntity> pageData = new PageData<UserEntity>(pageIndex, pageSize);
		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put("userName", userName);
		parameterMap.put("startRow", pageData.getStartRow());
		parameterMap.put("pageSize", pageSize);
		int totalCount = userDao.queryDataCount(userName);
		List<UserEntity> list = userDao.queryPageData(parameterMap);
		
		pageData.setTotalCount(totalCount);
		pageData.setPageData(list);
		
		return pageData;
		
	}
	
	public PageData<RoleEntity> getRoles(int pageIndex, int pageSize,String roleName){
		
		PageData<RoleEntity> pageData = new PageData<RoleEntity>(pageIndex, pageSize);
		
		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put("roleName", roleName);
		parameterMap.put("startRow", pageData.getStartRow());
		parameterMap.put("pageSize", pageSize);
		int totalCount = roleDao.queryDataCount(roleName);
		List<RoleEntity> list = roleDao.queryPageData(parameterMap);
		
		pageData.setTotalCount(totalCount);
		pageData.setPageData(list);
		
		return pageData;
		
	}
	
	public PageData<MenuEntity> getMenus(int pageIndex, int pageSize,String menuName){
		
		PageData<MenuEntity> pageData = new PageData<MenuEntity>(pageIndex, pageSize);
		
		
		
		int totalCount = menuDao.queryDataCount(menuName);
		Map<String, Object> parameterMap=new HashMap<String,Object>(3);
		parameterMap.put("menuName", menuName);
		parameterMap.put("startRow", pageData.getStartRow());
		parameterMap.put("pageSize", pageSize);
		List<MenuEntity> list = menuDao.queryPageData(parameterMap);
		
		pageData.setTotalCount(totalCount);
		pageData.setPageData(list);
		
		return pageData;
		
	}
	
	@Transactional
	public boolean saveUserRole(UserInfo userInfo) {
		String userId = userInfo.getId();
		//取用户
		userRoleDao.deleteByUserId(userId);
		//提交的角色ID
		List<String> roles = userInfo.getRoles();
		
		//判断是否有角色
		if(roles == null || roles.isEmpty()){
			return true;
		}
		for (String role : roles) {
			UserRole userRole=new UserRole();
			userRole.setRoleid(role);
			userRole.setId(UUIDGenerator.getUUID());
			userRole.setUserid(userId);
			
			try {
				userRoleDao.saveUserRole(userRole);
			} catch (Exception e) {
				logger.error(e.getMessage());
				return false;
			}
		}
		
		
		
		

		return true;
		
	}
	
	
	@Transactional
	public boolean saveRoleResource(String roleId,String[] mIds) {
//		
//		RoleEntity roleEntity = this.getRole(roleId);
//		
//		Set<MenuEntity> menus = new HashSet<MenuEntity>();
//		//提交的菜单ID
//		for (String menuId : mIds) {
//			MenuEntity menuEntity = this.getMenu(menuId);
//			menus.add(menuEntity);
//			//取菜单下所有子菜单
//			List<MenuEntity> childMenus = this.menuDao.getChildMenus(menuEntity.getId());
//			for (MenuEntity child : childMenus) {
//				menus.add(child);
//			}
//		}
//
//		
//		roleEntity.setMenus(menus);
//		//TODO 这里的错误
//		try {
//			this.roleDao.update(roleEntity);
//		} catch (Exception e) {
//			logger.error(e.getMessage());
//			return false;
//		}
//		
//		

		Set<MenuEntity> menus = new HashSet<MenuEntity>();
		this.roleMenuDao.deleteByRoleId(roleId);
		if(mIds == null || mIds.length == 0){
			return true;
		}
		//提交的菜单ID
		for (String menuId : mIds) {
			if(menuId == null || menuId.isEmpty()){
				break;
			}
			MenuEntity menuEntity = this.getMenu(menuId);
			menus.add(menuEntity);
			//取菜单下所有子菜单
			List<MenuEntity> childMenus = this.menuDao.getChildMenus(menuEntity.getId());
			for (MenuEntity child : childMenus) {
				menus.add(child);
			}
		}
		
		try {
			for(MenuEntity menu : menus){
				RoleMenu roleMenu = new RoleMenu();
				roleMenu.setId(UUIDGenerator.getUUID());
				roleMenu.setRoleid(roleId);
				roleMenu.setMenuid(menu.getId());
				this.roleMenuDao.saveRoleMenu(roleMenu);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		}
		return true;
	}

	public boolean checkUserNameIsExist(String userName) {
		return userDao.existUser(userName) > 0 ? true: false;
	}
	
	public boolean checkEmailIsExist(String email) {
		return userDao.existEmail(email) > 0 ? true : false;
	}
	
	@Transactional
	public void sendPwdGetBackEmail(String email){
		UserEntity user = userDao.getUserByEmail(email);
		EmailValEntity emailValEntity = new EmailValEntity();
		emailValEntity.setId(UUIDGenerator.getUUID());
		emailValEntity.setEmail(email);
		emailValEntity.setUserId(user.getId());
		emailValEntity.setUserName(user.getUserName());
		//生成过期时间 3天
		Date timeOut = DateUtil.addDay(DateUtil.getCurrentTime(), 3);
		emailValEntity.setTimeOut(timeOut);
		String code = CodeGenerator.getCode(emailValEntity);
		emailValEntity.setCode(code);
		try {
			emailValDao.save(emailValEntity);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		EmailUtil.sendEmailTo(email, code);
	}

	public boolean checkCode(String code) {
		// TODO check code
		EmailValEntity emailValEntity = emailValDao.getEmailValEntityIdByCode(code);
		if(emailValEntity == null){
			return false;
		}
		
		//检查code是否过期
		Date now = DateUtil.getCurrentTime();
		Date timeOut = emailValEntity.getTimeOut();
		
		if(now.compareTo(timeOut)>0){
			//链接已过期
			deleteEmailValEntity(emailValEntity);
			return false;
		}
		
		//TODO 这里需要改
		//		code一定会通过校验的，或许还需要一个参数来确定其唯一性
		//		状态字段目前没有，不知道链接是否被点过
		String checkCode = new StringBuffer(emailValEntity.getUserId())
					.append("$").append(emailValEntity.getUserName())
					.append(":").append(emailValEntity.getEmail())
					.append("!").append(DateUtil.getDateTimeStr(emailValEntity.getTimeOut())).toString();
		checkCode = DEncryptionUtils.saltMD5Encoder(checkCode);
		if(code.equals(checkCode)){
			return true;
		}else{
			//code未通过校验
			return false;
		}
	}
	
	@Transactional
	public void deleteEmailValEntity(EmailValEntity emailValEntity ){
		try {
			emailValDao.delete(emailValEntity);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
	}
	
	@Transactional
	public void deleteEmailValEntityByCode(String code) {
		try {
			emailValDao.deleteByCode(code);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
	}
	
	@Transactional
	public Map regist(UserEntity userEntity) {
		Map status = new HashMap();
		String userName = userEntity.getUserName();
		String email = userEntity.getEmail();
		
		if(userName==null||userName.isEmpty()){
			status.put("userName", "用户名不能为空！");
		}
		
		if(email==null||email.isEmpty()){
			status.put("email", "邮箱不能为空！");
		}

		boolean isEmail = ValidatorUtil.isEMail(email);
		if(!isEmail){
			status.put("email", "邮箱格式不正确！");
		}
		if(status.size()>0){
			return status;
		}
		
		//过滤非法字符
		userName = ValidatorUtil.filterUnSafeChar(userName);
		userEntity.setUserName(userName);
		
		userEntity.setStatus(1);
		userEntity.setId(UUIDGenerator.getUUID());
		userEntity.setCreateTime(DateUtil.getCurrentTime());
		userEntity.setLastUpdate(DateUtil.getCurrentTime());
		userEntity.setPassWord(MD5.getMD5Encoding(userEntity.getPassWord()));
		
		UserRole userRole = new UserRole();
		userRole.setId(UUIDGenerator.getUUID());
		userRole.setUserid(userEntity.getId());
		//TODO 是否需要写一个特殊的角色给刚注册的用户
		userRole.setRoleid("2");
		userDao.save(userEntity);
		userRoleDao.saveUserRole(userRole);
		
		return status;
	}
	
	public String getUserIdByCode(String code) {
		try {
			return emailValDao.getUserIdByCode(code);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return null;
	}
	
	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public RoleDao getRoleDao() {
		return roleDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	public MenuDao getMenuDao() {
		return menuDao;
	}

	public void setMenuDao(MenuDao menuDao) {
		this.menuDao = menuDao;
	}

	public RoleMenuDao getRoleMenuDao() {
		return roleMenuDao;
	}

	public void setRoleMenuDao(RoleMenuDao roleMenuDao) {
		this.roleMenuDao = roleMenuDao;
	}

	public UserRoleDao getUserRoleDao() {
		return userRoleDao;
	}

	public void setUserRoleDao(UserRoleDao userRoleDao) {
		this.userRoleDao = userRoleDao;
	}

}
